package cevent.source.cloudcenter.server.service;

import cevent.source.cloudcenter.server.domain.ShortMessage;
import cevent.source.cloudcenter.server.domain.ShortMessageExample;
import cevent.source.cloudcenter.server.dto.PageDto;
import cevent.source.cloudcenter.server.dto.ShortMessageDto;
import cevent.source.cloudcenter.server.enums.ShortMessageStatusEnum;
import cevent.source.cloudcenter.server.exception.BusinessException;
import cevent.source.cloudcenter.server.exception.BusinessExceptionCode;
import cevent.source.cloudcenter.server.mapper.ShortMessageMapper;
import cevent.source.cloudcenter.server.util.DuplicateUtil;
import cevent.source.cloudcenter.server.util.UUID8Util;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author cevent
 * @description 短信管理表服务层
 */
@Service
public class ShortMessageService {
    private static final Logger LOG=LoggerFactory.getLogger(ShortMessageService.class);

    @Value("${shortMessageAccessKeyID}")
    private String shortMessageAccessKeyID;
    @Value("${shortMessageAccessKeySecret}")
    private String shortMessageAccessKeySecret;

    @Resource
    private ShortMessageMapper shortMessageMapper;

    //1.无分页列表查询：dto获取domain参数
    public List<ShortMessageDto> shortMessageDtoList(){
        ShortMessageExample shortMessageExample = new ShortMessageExample();
        shortMessageExample.setOrderByClause("uni_id asc");
        List<ShortMessage> shortMessageList=shortMessageMapper.selectByExample(shortMessageExample);
        List<ShortMessageDto> shortMessageDtoList = new ArrayList<ShortMessageDto>();
        for(int i=0;i<shortMessageList.size();i++){
            ShortMessage shortMessage=shortMessageList.get(i);
            ShortMessageDto shortMessageDto=new ShortMessageDto();
            //复制拷贝(source,target)
            BeanUtils.copyProperties(shortMessage,shortMessageDto);
            shortMessageDtoList.add(shortMessageDto);
        }
        return shortMessageDtoList;
    }

    /*2.分页查询：pageDto保存数据
        list数据集合：listPageData
        当前页码：currentPage
        每页行数：size
        总计函数：totalSize
        前端可返回pageDto，无需返回值
     */
    public void getShortMessagePageDtoList(PageDto pageDto){
        //1.分页设置（前端传入当前页和每页行数params），起始页，每页行数size
        PageHelper.startPage(pageDto.getCurrentPage(),pageDto.getSize());

        ShortMessageExample shortMessageExample=new ShortMessageExample();


        List<ShortMessage> shortMessageList=shortMessageMapper.selectByExample(shortMessageExample);
        //2.将mapper查询结果复制到pageInfo
        PageInfo<ShortMessage> pageInfo=new PageInfo<>(shortMessageList);
        //3.pageInfo计算处理处理=>后分页的总行数set到pageDto做记录
        pageDto.setTotalSize(pageInfo.getTotal());

        List<ShortMessageDto> shortMessageDtoList=new ArrayList<>();
        shortMessageList.stream().forEach(shortMessage->{
            ShortMessageDto shortMessageDto=new ShortMessageDto();
            BeanUtils.copyProperties(shortMessage,shortMessageDto);
            shortMessageDtoList.add(shortMessageDto);
        });

        pageDto.setListPageData(shortMessageDtoList);

    }

    //3.新增、修改shortMessage，将传入的id转为shortMessage对象本身
    public void save(ShortMessageDto shortMessageDto){
        ShortMessage shortMessage= DuplicateUtil.copy(shortMessageDto,ShortMessage.class);
        if(StringUtils.isEmpty(shortMessageDto.getUniId())){
            this.insert(shortMessage);
        }else{
            this.update(shortMessage);
        }

    }

    //4.删除模块
    public void delete(String uniId){
        ShortMessageExample shortMessageExample=new ShortMessageExample();
        shortMessageMapper.deleteByPrimaryKey(uniId);
    }

    //5.向外暴露dto，不暴露实体类：插入数据
    private void insert(ShortMessage shortMessage){
        shortMessage.setUniId(UUID8Util.getShortUUID());

        try {
        Date now =new Date();
        String date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
        long time=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date).getTime();
        int timeInt=(int)(time/1000);
            shortMessage.setTimes(now);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        shortMessageMapper.insert(shortMessage);
    }

    //6.更新模块
    private void update(ShortMessage shortMessage){
        try {
            Date now =new Date();
            String date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
            long time=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date).getTime();
            int timeInt=(int)(time/1000);
            shortMessage.setTimes(now);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        shortMessageMapper.updateByPrimaryKey(shortMessage);
    }

    //前端：管理端发送验证码
    public ShortMessageDto sendShortMessage(ShortMessageDto shortMessageDto){
        LOG.info("发送到后端的shortMessageDto：{}",shortMessageDto);
        ShortMessageExample shortMessageExample=new ShortMessageExample();
        ShortMessageExample.Criteria criteria=shortMessageExample.createCriteria();
        //获取手机号，一分钟内没有，并且not_used
        criteria.andMobileEqualTo(shortMessageDto.getMobile())
                .andUseEqualTo(shortMessageDto.getUse())
                .andStatusEqualTo(ShortMessageStatusEnum.NOT_USED.getCode()) //验证码未使用1分钟
                .andTimesGreaterThan(new Date(new Date().getTime()- 1*60*1000)); //1分钟
        List<ShortMessage> shortMessageList=shortMessageMapper.selectByExample(shortMessageExample);

        //保存code
        //生成6位数字
        String code=String.valueOf((int)(((Math.random()*9)+1)*100000));
        shortMessageDto.setTimes(new Date());
        shortMessageDto.setCode(code);
        shortMessageDto.setName(shortMessageDto.getName());
        shortMessageDto.setContent(shortMessageDto.getContent());
        shortMessageDto.setStatus(ShortMessageStatusEnum.USED.getCode());
        this.save(shortMessageDto);
        //不存在则发送
        if(shortMessageList==null || shortMessageList.size()==0){

            //TODO 第三方短信发送通道
            // 1.可接阿里云短信服务，在控台配置短信模板
            // 2.在代码里配置短信id，调用阿里云jar包。收费：0.045/条
            DefaultProfile defaultProfile=DefaultProfile.getProfile("cn-hangzhou",shortMessageAccessKeyID,shortMessageAccessKeySecret);
            IAcsClient iAcsClient=new DefaultAcsClient(defaultProfile);

            CommonRequest commonRequest=new CommonRequest();
            //设置发送请求方法
            commonRequest.setSysMethod(MethodType.POST);
            //设置发送短信服务器，默认为dysmsapi.aliyuncs.com
            commonRequest.setSysDomain("dysmsapi.aliyuncs.com");
            //设置版本，默认为2017-05-25
            commonRequest.setSysVersion("2017-05-25");
            //设置调用的API方法名
            commonRequest.setSysAction("SendSms");
            commonRequest.putQueryParameter("RegionId","cn-hangzhou");
            //接收短信的电话号码
            commonRequest.putQueryParameter("PhoneNumbers",shortMessageDto.getMobile());
            //短信签名，如【阿里云】，须申请，使用申请成功的签名
            commonRequest.putQueryParameter("SignName","衡水国礼");
            //短信模板，须申请，使用申请成功的短信模板的模版CODE
            commonRequest.putQueryParameter("TemplateCode","SMS_151178787");
            //申请的短信模板中的变量code的值，如验证码，字符串格式必须为"{code:number}"，否则报错
            commonRequest.putQueryParameter("TemplateParam","{code:"+shortMessageDto.getCode()+"}");
            LOG.info("短信发送请求：{},短信内容json：{}",commonRequest,"{code:"+shortMessageDto.getCode()+"}");

            //接收回调
            try {
                CommonResponse commonResponse=iAcsClient.getCommonResponse(commonRequest);
                LOG.info("短信发送成功：{}",commonResponse);
            } catch (ClientException e) {
                e.printStackTrace();
            }
            return shortMessageDto;
        }else{
            throw new BusinessException(BusinessExceptionCode.SHORT_MESSAGE_SEND_FREQUENT);
        }

    }
    //后台：保存短信并发送短信
    public void saveAndSendShortMessage(ShortMessageDto shortMessageDto){
        //生成6位数字
        String code=String.valueOf((int)(((Math.random()*9)+1)*100000));
        shortMessageDto.setTimes(new Date());
        shortMessageDto.setCode(code);
        shortMessageDto.setName(shortMessageDto.getName());
        shortMessageDto.setContent(shortMessageDto.getContent());
        shortMessageDto.setStatus(ShortMessageStatusEnum.USED.getCode());
        this.save(shortMessageDto);

        //TODO 第三方短信发送通道
        // 1.可接阿里云短信服务，在控台配置短信模板
        // 2.在代码里配置短信id，调用阿里云jar包。收费：0.045/条
        DefaultProfile defaultProfile=DefaultProfile.getProfile("cn-hangzhou",shortMessageAccessKeyID,shortMessageAccessKeySecret);
        IAcsClient iAcsClient=new DefaultAcsClient(defaultProfile);

        CommonRequest commonRequest=new CommonRequest();
        //设置发送请求方法
        commonRequest.setSysMethod(MethodType.POST);
        //设置发送短信服务器，默认为dysmsapi.aliyuncs.com
        commonRequest.setSysDomain("dysmsapi.aliyuncs.com");
        //设置版本，默认为2017-05-25
        commonRequest.setSysVersion("2017-05-25");
        //设置调用的API方法名
        commonRequest.setSysAction("SendSms");
        commonRequest.putQueryParameter("RegionId","cn-hangzhou");
        //接收短信的电话号码
        commonRequest.putQueryParameter("PhoneNumbers",shortMessageDto.getMobile());
        //短信签名，如【阿里云】，须申请，使用申请成功的签名
        commonRequest.putQueryParameter("SignName","衡水国礼");
        //短信模板，须申请，使用申请成功的短信模板的模版CODE
        commonRequest.putQueryParameter("TemplateCode","SMS_221071513");
        //申请的短信模板中的变量code的值,code属于json字符串,多个参数{"param1":"","param2":""}每个属性前后都必须加入转译字符
        commonRequest.putQueryParameter("TemplateParam","{\"name\":\""+shortMessageDto.getName()+"\",\"content\":\""+shortMessageDto.getContent()+"\"}");
        /*LOG.info("短信发送请求：{}，传入的JSON: {}",commonRequest,"{\"name\":\""+shortMessageDto.getName()+"\",\"content\":\""+shortMessageDto.getContent()+"\"}");*/

        //接收回调
        try {
            CommonResponse commonResponse=iAcsClient.getCommonResponse(commonRequest);
            LOG.info("短信发送成功：{}",commonResponse);
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }

    //校验短信验证码
    public void validShortMessageCode(ShortMessageDto shortMessageDto){
        //查询五分钟以内发送验证码的手机号，验证码5分钟有效
        ShortMessageExample shortMessageExample=new ShortMessageExample();
        ShortMessageExample.Criteria criteria=shortMessageExample.createCriteria();
        criteria.andMobileEqualTo(shortMessageDto.getMobile())
                .andUseEqualTo(shortMessageDto.getUse())
                .andTimesGreaterThan(new Date(new Date().getTime()-5*60*1000));//greaterThan大于>?
        List<ShortMessage> shortMessageList=shortMessageMapper.selectByExample(shortMessageExample);
        LOG.info("获取到的shortMessage：{}",shortMessageList);
        if(shortMessageList!=null && shortMessageList.size()>0){
            ShortMessage shortMessage=shortMessageList.get(0);
            if(!shortMessage.getCode().equals(shortMessageDto.getCode())){
                LOG.info("短信验证码输入错误，请重新输入");
                throw new BusinessException(BusinessExceptionCode.SHORT_MESSAGE_INPUT_ERROR);
            }else{
                shortMessage.setStatus(ShortMessageStatusEnum.USED.getCode());
                shortMessageMapper.updateByPrimaryKey(shortMessage);
            }
        }else{
            LOG.info("短信验证码不存在");
            throw new BusinessException(BusinessExceptionCode.SHORT_MESSAGE_UN_EXIST);
        }
    }
}
